home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 1 / QRZ Ham Radio Callsign Database - December 1993.iso / ucsd / packet / tcpip / sys5 / iscwmpst.z / iscwmpst / tcp / src / iface.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-19  |  10.2 KB  |  425 lines

  1. /* @(#) $Header: iface.c,v 1.8 91/06/18 17:26:59 deyke Exp $ */
  2.  
  3. /* IP interface control and configuration routines
  4.  * Copyright 1991 Phil Karn, KA9Q
  5.  */
  6. #include <stdio.h>
  7. #include "global.h"
  8. #include "mbuf.h"
  9. #include "proc.h"
  10. #include "iface.h"
  11. #include "ip.h"
  12. #include "netuser.h"
  13. #include "ax25.h"
  14. #include "enet.h"
  15. #include "pktdrvr.h"
  16. #include "cmdparse.h"
  17. #include "commands.h"
  18.  
  19. static void showiface __ARGS((struct iface *ifp));
  20. static int mask2width __ARGS((int32 mask));
  21. static int ifipaddr __ARGS((int argc,char *argv[],void *p));
  22. static int iflinkadr __ARGS((int argc,char *argv[],void *p));
  23. static int ifbroad __ARGS((int argc,char *argv[],void *p));
  24. static int ifnetmsk __ARGS((int argc,char *argv[],void *p));
  25. static int ifrxbuf __ARGS((int argc,char *argv[],void *p));
  26. static int ifmtu __ARGS((int argc,char *argv[],void *p));
  27. static int ifforw __ARGS((int argc,char *argv[],void *p));
  28. static int ifencap __ARGS((int argc,char *argv[],void *p));
  29. static int ifcrc __ARGS((int argc,char *argv[],void *p));
  30.  
  31. /* Interface list header */
  32. struct iface *Ifaces = &Loopback;
  33.  
  34. /* Loopback pseudo-interface */
  35. struct iface Loopback = {
  36.     &Encap,         /* Link to next entry */
  37.     "loopback",     /* name         */
  38.     CL_NONE,        /* type         */
  39.     &Iftypes[0],    /* iftype       */
  40.     0x7f000001L,    /* addr         127.0.0.1 */
  41.     0xffffffffL,    /* broadcast    255.255.255.255 */
  42.     0xffffffffL,    /* netmask      255.255.255.255 */
  43.     NULL,           /* (*ioctl)     */
  44.     NULLFP,         /* (*iostatus)  */
  45.     NULLFP,         /* (*send)      */
  46.     NULLFP,         /* (*output)    */
  47.     NULLFP,         /* (*raw)       */
  48.     NULLFP,         /* (*stop)      */
  49.     NULLFP,         /* (*status)    */
  50.     MAXINT16,       /* mtu          No limit */
  51.     0,              /* dev          */
  52.     0,              /* xdev         */
  53.     0,              /* flags        */
  54.     0,              /* trace        */
  55.     NULLCHAR,       /* trfile       */
  56.     NULLFILE,       /* trfp         */
  57.     NULLCHAR,       /* hwaddr       */
  58.     NULLIF,         /* forw         */
  59.     0,              /* ipsndcnt     */
  60.     0,              /* rawsndcnt    */
  61.     0,              /* iprcvcnt     */
  62.     0,              /* rawrcvcnt    */
  63.     0,              /* lastsent     */
  64.     0,              /* lastrecv     */
  65.     NULL,           /* rxproc       */
  66.     NULL,           /* txproc       */
  67.     NULL,           /* supv         */
  68.     0,              /* sendcrc      */
  69.     0,              /* crcerrors    */
  70.     NULL,           /* extension    */
  71.     NULLFP,         /* (*discard)   */
  72.     NULLFP,         /* (*echo)      */
  73. };
  74. /* Encapsulation pseudo-interface */
  75. struct iface Encap = {
  76.     NULLIF,
  77.     "encap",        /* name         */
  78.     CL_NONE,        /* type         */
  79.     &Iftypes[0],    /* iftype       */
  80.     INADDR_ANY,     /* addr         0.0.0.0 */
  81.     0xffffffffL,    /* broadcast    255.255.255.255 */
  82.     0xffffffffL,    /* netmask      255.255.255.255 */
  83.     NULL,           /* (*ioctl)     */
  84.     NULLFP,         /* (*iostatus)  */
  85.     ip_encap,       /* (*send)      */
  86.     NULLFP,         /* (*output)    */
  87.     NULLFP,         /* (*raw)       */
  88.     NULLFP,         /* (*stop)      */
  89.     NULLFP,         /* (*status)    */
  90.     MAXINT16,       /* mtu          No limit */
  91.     0,              /* dev          */
  92.     0,              /* xdev         */
  93.     0,              /* flags        */
  94.     0,              /* trace        */
  95.     NULLCHAR,       /* trfile       */
  96.     NULLFILE,       /* trfp         */
  97.     NULLCHAR,       /* hwaddr       */
  98.     NULLIF,         /* forw         */
  99.     0,              /* ipsndcnt     */
  100.     0,              /* rawsndcnt    */
  101.     0,              /* iprcvcnt     */
  102.     0,              /* rawrcvcnt    */
  103.     0,              /* lastsent     */
  104.     0,              /* lastrecv     */
  105.     NULL,           /* rxproc       */
  106.     NULL,           /* txproc       */
  107.     NULL,           /* supv         */
  108.     0,              /* sendcrc      */
  109.     0,              /* crcerrors    */
  110.     NULL,           /* extension    */
  111.     NULLFP,         /* (*discard)   */
  112.     NULLFP,         /* (*echo)      */
  113. };
  114.  
  115. char Noipaddr[] = "IP address field missing, and ip address not set\n";
  116.  
  117. struct cmds Ifcmds[] = {
  118.     "broadcast",            ifbroad,        0,      2,      NULLCHAR,
  119.     "crc",                  ifcrc,          0,      2,      NULLCHAR,
  120.     "encapsulation",        ifencap,        0,      2,      NULLCHAR,
  121.     "forward",              ifforw,         0,      2,      NULLCHAR,
  122.     "ipaddress",            ifipaddr,       0,      2,      NULLCHAR,
  123.     "linkaddress",          iflinkadr,      0,      2,      NULLCHAR,
  124.     "mtu",                  ifmtu,          0,      2,      NULLCHAR,
  125.     "netmask",              ifnetmsk,       0,      2,      NULLCHAR,
  126.     "rxbuf",                ifrxbuf,        0,      2,      NULLCHAR,
  127.     NULLCHAR,
  128. };
  129.  
  130. /* Set interface parameters */
  131. int
  132. doifconfig(argc,argv,p)
  133. int argc;
  134. char *argv[];
  135. void *p;
  136. {
  137.     struct iface *ifp;
  138.     int i;
  139.  
  140.     if(argc < 2){
  141.         for(ifp = Ifaces;ifp != NULLIF;ifp = ifp->next)
  142.             showiface(ifp);
  143.         return 0;
  144.     }
  145.     if((ifp = if_lookup(argv[1])) == NULLIF){
  146.         tprintf("Interface %s unknown\n",argv[1]);
  147.         return 1;
  148.     }
  149.     if(argc == 2){
  150.         showiface(ifp);
  151.         if ( ifp->status != NULLFP ) {
  152.             (*ifp->status)(ifp);
  153.         }
  154.         return 0;
  155.     }
  156.     if(argc == 3){
  157.         tprintf("Argument missing\n");
  158.         return 1;
  159.     }
  160.     for(i=2;i<argc-1;i+=2)
  161.         subcmd(Ifcmds,3,&argv[i-1],ifp);
  162.  
  163.     return 0;
  164. }
  165.  
  166. /* Set interface IP address */
  167. static int
  168. ifipaddr(argc,argv,p)
  169. int argc;
  170. char *argv[];
  171. void *p;
  172. {
  173.     struct iface *ifp = p;
  174.  
  175.     ifp->addr = resolve(argv[1]);
  176.     return 0;
  177. }
  178.  
  179. /* Set link (hardware) address */
  180. static int
  181. iflinkadr(argc,argv,p)
  182. int argc;
  183. char *argv[];
  184. void *p;
  185. {
  186.     struct iface *ifp = p;
  187.  
  188.     if(ifp->iftype == NULLIFT || ifp->iftype->scan == NULL){
  189.         tprintf("Can't set link address\n");
  190.         return 1;
  191.     }
  192.     if(ifp->hwaddr != NULLCHAR)
  193.         free(ifp->hwaddr);
  194.     ifp->hwaddr = mallocw(ifp->iftype->hwalen);
  195.     (*ifp->iftype->scan)(ifp->hwaddr,argv[1]);
  196.     return 0;
  197. }
  198.  
  199. /* Set interface broadcast address. This is actually done
  200.  * by installing a private entry in the routing table.
  201.  */
  202. static int
  203. ifbroad(argc,argv,p)
  204. int argc;
  205. char *argv[];
  206. void *p;
  207. {
  208.     struct iface *ifp = p;
  209.     struct route *rp;
  210.  
  211.     rp = rt_blookup(ifp->broadcast,32);
  212.     if(rp != NULLROUTE && rp->iface == ifp)
  213.         rt_drop(ifp->broadcast,32);
  214.     ifp->broadcast = resolve(argv[1]);
  215.     rt_add(ifp->broadcast,32,0L,ifp,1L,0L,1);
  216.     return 0;
  217. }
  218.  
  219. /* Set the network mask. This is actually done by installing
  220.  * a routing entry.
  221.  */
  222. static int
  223. ifnetmsk(argc,argv,p)
  224. int argc;
  225. char *argv[];
  226. void *p;
  227. {
  228.     struct iface *ifp = p;
  229.     struct route *rp;
  230.  
  231.     /* Remove old entry if it exists */
  232.     rp = rt_blookup(ifp->addr & ifp->netmask,mask2width(ifp->netmask));
  233.     if(rp != NULLROUTE)
  234.         rt_drop(rp->target,rp->bits);
  235.  
  236.     ifp->netmask = htol(argv[1]);
  237.     rt_add(ifp->addr,mask2width(ifp->netmask),0L,ifp,0L,0L,0);
  238.     return 0;
  239. }
  240.  
  241. /* Command to set interface encapsulation mode */
  242. static int
  243. ifencap(argc,argv,p)
  244. int argc;
  245. char *argv[];
  246. void *p;
  247. {
  248.     struct iface *ifp = p;
  249.  
  250.     if(setencap(ifp,argv[1]) != 0){
  251.         tprintf("Encapsulation mode '%s' unknown\n",argv[1]);
  252.         return 1;
  253.     }
  254.     return 0;
  255. }
  256. /* Function to set encapsulation mode */
  257. int
  258. setencap(ifp,mode)
  259. struct iface *ifp;
  260. char *mode;
  261. {
  262.     struct iftype *ift;
  263.  
  264.     for(ift = &Iftypes[0];ift->name != NULLCHAR;ift++)
  265.         if(strnicmp(ift->name,mode,strlen(mode)) == 0)
  266.             break;
  267.     if(ift->name == NULLCHAR){
  268.         return -1;
  269.     }
  270.     ifp->iftype = ift;
  271.     ifp->send = ift->send;
  272.     ifp->output = ift->output;
  273.     ifp->type = ift->type;
  274.     return 0;
  275. }
  276. /* Set interface receive buffer size */
  277. static int
  278. ifrxbuf(argc,argv,p)
  279. int argc;
  280. char *argv[];
  281. void *p;
  282. {
  283.     return 0;       /* To be written */
  284. }
  285.  
  286. /* Set interface Maximum Transmission Unit */
  287. static int
  288. ifmtu(argc,argv,p)
  289. int argc;
  290. char *argv[];
  291. void *p;
  292. {
  293.     struct iface *ifp = p;
  294.  
  295.     ifp->mtu = atoi(argv[1]);
  296.     return 0;
  297. }
  298.  
  299. /* Set interface forwarding */
  300. static int
  301. ifforw(argc,argv,p)
  302. int argc;
  303. char *argv[];
  304. void *p;
  305. {
  306.     struct iface *ifp = p;
  307.  
  308.     ifp->forw = if_lookup(argv[1]);
  309.     if(ifp->forw == ifp)
  310.         ifp->forw = NULLIF;
  311.     return 0;
  312. }
  313.  
  314. static int
  315. ifcrc(argc,argv,p)
  316. int argc;
  317. char *argv[];
  318. void *p;
  319. {
  320.     struct iface *ifp = p;
  321.  
  322.     return setbool(&ifp->sendcrc, "CRC generation", argc, argv);
  323. }
  324.  
  325. /* Display the parameters for a specified interface */
  326. static void
  327. showiface(ifp)
  328. register struct iface *ifp;
  329. {
  330.     char tmp[25];
  331.  
  332.     tprintf("%-10s IP addr %s MTU %u Link encap ",ifp->name,
  333.      inet_ntoa(ifp->addr),(int)ifp->mtu);
  334.     if(ifp->iftype == NULLIFT){
  335.         tprintf("not set\n");
  336.     } else {
  337.         tprintf("%s\n",ifp->iftype->name);
  338.         if(ifp->iftype->format != NULL && ifp->hwaddr != NULLCHAR)
  339.             tprintf("           Link addr %s\n",
  340.              (*ifp->iftype->format)(tmp,ifp->hwaddr));
  341.     }
  342.     tprintf("           flags %u trace 0x%x netmask 0x%08lx broadcast %s\n",
  343.         ifp->flags,ifp->trace,ifp->netmask,inet_ntoa(ifp->broadcast));
  344.     if(ifp->forw != NULLIF)
  345.         tprintf("           output forward to %s\n",ifp->forw->name);
  346.     tprintf("           sent: ip %lu tot %lu idle %s\n",
  347.      ifp->ipsndcnt,ifp->rawsndcnt,tformat(secclock() - ifp->lastsent));
  348.     tprintf("           recv: ip %lu tot %lu idle %s\n",
  349.      ifp->iprecvcnt,ifp->rawrecvcnt,tformat(secclock() - ifp->lastrecv));
  350.     tprintf("           CRC %s errors %lu\n",
  351.      ifp->sendcrc ? "enabled" : "disabled", ifp->crcerrors);
  352.     tprintf("\n");
  353. }
  354.  
  355. /* Given the ascii name of an interface, return a pointer to the structure,
  356.  * or NULLIF if it doesn't exist
  357.  */
  358. struct iface *
  359. if_lookup(name)
  360. char *name;
  361. {
  362.     register struct iface *ifp;
  363.  
  364.     for(ifp = Ifaces; ifp != NULLIF; ifp = ifp->next)
  365.         if(strcmp(ifp->name,name) == 0)
  366.             break;
  367.     return ifp;
  368. }
  369.  
  370. /* Return iface pointer if 'addr' belongs to one of our interfaces,
  371.  * NULLIF otherwise.
  372.  * This is used to tell if an incoming IP datagram is for us, or if it
  373.  * has to be routed.
  374.  */
  375. struct iface *
  376. ismyaddr(addr)
  377. int32 addr;
  378. {
  379.     register struct iface *ifp;
  380.  
  381.     for(ifp = Ifaces; ifp != NULLIF; ifp = ifp->next)
  382.         if(addr == ifp->addr)
  383.             break;
  384.     return ifp;
  385. }
  386.  
  387. /* Given a network mask, return the number of contiguous 1-bits starting
  388.  * from the most significant bit.
  389.  */
  390. static int
  391. mask2width(mask)
  392. int32 mask;
  393. {
  394.     int width,i;
  395.  
  396.     width = 0;
  397.     for(i = 31;i >= 0;i--){
  398.         if(!(mask & (1L << i)))
  399.             break;
  400.         width++;
  401.     }
  402.     return width;
  403. }
  404.  
  405. /* return buffer with name + comment */
  406. char *
  407. if_name(ifp,comment)
  408. struct iface *ifp;
  409. char *comment;
  410. {
  411.     char *result = mallocw( strlen(ifp->name) + strlen(comment) + 1 );
  412.     strcpy( result, ifp->name );
  413.     return strcat( result, comment );
  414. }
  415.  
  416. /* Raw output routine that tosses all packets. Used by dialer, tip, etc */
  417. int
  418. bitbucket(ifp,bp)
  419. struct iface *ifp;
  420. struct mbuf *bp;
  421. {
  422.     free_p(bp);
  423.     return 0;
  424. }
  425.